import requests
import re
from multiprocessing import Pool
import os
requests.packages.urllib3.disable_warnings()
start_url = 'https://www.kanunu8.com/book3/8469/'

def get_source(url):
    """
    获取网页源代码。
    :param url: 网址
    :return: 网页源代码
    """
    headers = {
    'User-Agent':'Mozilla/5.0(Linux; Android 6.0; Nexus 5 Build/MRA58N)AppleWebKit/537.36 (KHTML,like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36'
}
    html = requests.get(url, headers=headers,verify=False)
    #print(html.content.decode('gbk'))
    return html.content.decode('gbk') #这个网页需要使用gbk方式解码才能让中文正常显示
def get_toc(html):
    """
    获取每一章链接，储存到一个列表中并返回。
    :param html: 目录页源代码
    :return: 每章链接
    """
    print(html)
    toc_url_list = []
    toc_block = re.findall('正文(.*?)</tbody>', html, re.S)[0]
    # print(toc_block)
    toc_url = re.findall('href="(.*?)"', toc_block, re.S)
    # print(toc_url)
    for url in toc_url:
        toc_url_list.append(start_url + url)
    print(toc_url_list)
    return toc_url_list
def get_article(html):
    """
    获取每一章的正文并返回章节名和正文。
    :param html: 正文源代码
    :return: 章节名，正文
    """
    chapter_name = re.search('size="4">(.*?)<', html, re.S).group(1)#获取标题
    text_block = re.search('<p>(.*?)</p>', html, re.S).group(1)#获取文章内容
    text_block = text_block.replace('&nbsp;', '')#去除空格
    text_block = text_block.replace('<br />', '')#去除换行
    return chapter_name, text_block
def save(chapter, article):
    """
    将每一章保存到本地。
    :param chapter: 章节名, 第X章
    :param article: 正文内容
    :return: None
    """
    os.makedirs('青耳', exist_ok=True) #如果没有小说文件夹，就创建一个，如果有，则什么都不做"
    with open(os.path.join('青耳', chapter + '.txt'), 'w', encoding='utf-8') as f:
        f.write(article)
def query_article(url):
    """
    根据正文网址获取正文源代码，并调用get_article函数获得正文内容最后保存到本地。
    :param url: 正文网址
    :return: None
    """
    article_html = get_source(url)
    # print(article_html)
    chapter_name, article_text = get_article(article_html)
    # print(chapter_name, article_text)
    save(chapter_name, article_text)
if __name__ == '__main__':
    toc_html = get_source(start_url)
    # print(toc_html)
    toc_list = get_toc(toc_html)
    # print(toc_list)
    # print(toc_list[0])
    # query_article(toc_list[0])
    pool = Pool(4)# 创建进程池
    pool.map(query_article, toc_list)
    # map函数需要传递两个参数，第一个参数就是需要引用的函数，第二个参数是一个可迭代对象
    #多进程的创建，应用在爬虫中主要目的是提高爬取的效率，实现秒爬
    print("下载已完成")

